<template>
  <view>
    <view v-if="showGuide" class="outer" @touchmove.stop.prevent="moveHandle">
      <view class="inner" :style="[innerStyle]"></view>
      <view class="innerText" :style="[innerTextStyle]">
        <view
          v-if="nextBtnPosition === 'top' && showNextButton"
          class="next-btn-wrap"
        >
          <slot name="nextButton">
            <view class="next-btn" @click="nextGuide">{{
              guide !== lastIndex ? "下一步" : "完成"
            }}</view>
          </slot>
        </view>
        <text :style="[textStyle]">{{ innerText }}</text>
        <view
          v-if="nextBtnPosition === 'bottom' && showNextButton"
          class="next-btn-wrap"
        >
          <slot name="nextButton">
            <view class="next-btn" @click="nextGuide">{{
              guide !== lastIndex ? "下一步" : "完成"
            }}</view>
          </slot>
        </view>
      </view>
    </view>
  </view>
</template>

<script>
export default {
  name: "mask-guide",
  props: {
    lastIndex: {
      type: Number,
      default: 0,
    },
  },
  data() {
    return {
      innerStyle: {},
      innerTextStyle: {},
      guide: 0,
      showGuide: false,
      innerText: "",
      deviceInfo: {},
      textStyle: {},
      showNextButton: true,
      nextBtnPosition: "top",
    };
  },
  methods: {
    start(props) {
      for (let k in props) {
        this[k] = props[k];
      }
      this.deviceInfo = uni.getSystemInfoSync();
      this.showGuide = true;
      this.nextGuide();
    },
    moveHandle() {},
    nextGuide() {
      const index = this.guide;
      uni
        .createSelectorQuery()
        .select(`#guide-container>>>#guide_${index}`)
        .fields(
          {
            id: true,
            dataset: true,
            rect: true,
            size: true,
            scrollOffset: true,
            context: true,
            properties: ["scrollX", "scrollY"],
            computedStyle: ["borderRadius"],
          },
          (data) => {
            if (data) {
              let { left, right, top, width, height, borderRadius, dataset } =
                data;
              //判断是否需要滚动
              let { windowHeight } = this.deviceInfo;
              this.innerStyle = {
                left: `${left}px`,
                top: `${top}px`,
                width: `${width}px`,
                height: `${height}px`,
                borderRadius: borderRadius,
              };
              //根据位置设置显示的位置
              const leftRpx = this.pxToRpx(left);
              let innerTextStyle = {
                top: `${top + height + 5}px`,
              };
              if (leftRpx > 400) {
                innerTextStyle.textAlign = "right";
                innerTextStyle.right = `${750 - this.pxToRpx(right)}rpx`;
                innerTextStyle.marginLeft = `10px`;
              } else {
                innerTextStyle.textAlign = "left";
                innerTextStyle.left = `${left}px`;
                innerTextStyle.marginRight = `10px`;
              }
              //如果长度够长 居中显示
              if (width > 300) {
                innerTextStyle.width = `${width}px`;
                innerTextStyle.textAlign = "center";
              }
              //内容在可视区域以下
              console.log("内容在可视区域以下", windowHeight, top);
              if (windowHeight < top) {
                uni.pageScrollTo({
                  scrollTop: top - windowHeight + height + 10,
                  duration: 0,
                });
                this.innerStyle.top = `${windowHeight - height - 10}px`;
              }
              //内容在可视区域以上
              if (top < 0) {
                uni.pageScrollTo({
                  scrollTop: top,
                  duration: 0,
                });
                this.nextGuide();
                return;
              }
              //如果在可视区域下方，提示文字显示在上方
              if (parseFloat(this.innerStyle.top) > windowHeight / 2) {
                innerTextStyle.bottom = `${
                  windowHeight - parseFloat(this.innerStyle.top) + 10
                }px`;
                delete innerTextStyle.top;
                this.nextBtnPosition = "top";
              } else {
                this.nextBtnPosition = "bottom";
              }
              this.innerTextStyle = innerTextStyle;
              this.innerText = dataset.guideText ?? "";
              this.guide++;
            } else {
              this.showGuide = false;
              uni.pageScrollTo({
                scrollTop: 0,
                duration: 0,
              });
              this.guide = 0;
            }
          }
        )
        .exec();
    },
    pxToRpx(val) {
      return val / (uni.upx2px(100) / 100);
    },
  },
};
</script>

<style>
.outer {
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  background: transparent;
  overflow: hidden;
  z-index: 99999;
}

.inner {
  position: absolute;
  box-shadow: rgba(61, 61, 61, 0.6) 0 0 0 2021px;
  z-index: 99999;
}

.innerText {
  color: #fff;
  position: absolute;
  z-index: 99999;
  font-size: 28rpx;
  letter-spacing: 2rpx;
  text-align: center;
}
.next-btn-wrap {
  display: flex;
  justify-content: center;
  align-items: center;
}
.next-btn {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 60rpx;
  padding: 0 30rpx;
  border-radius: 10rpx;
  margin: 10rpx;
  font-size: 26rpx;
  background-color: white;
  color: black;
}
</style>
